﻿using System;
using InterfacesPhoneCommands;

namespace PhoneControl
{
    public class PhoneService : WcfWindowsServicesHost, IPhoneService
    {
        private Exception _critialError;

        private PhoneService()
            : base(typeof (PhoneService))
        {
            _critialError = null;

            PhoneControl.Instance.ChangedMachineStatus += InstanceChangedMachineStatus;

        }

        private void InstanceChangedMachineStatus(object sender, ChangedMachineStatusEventArgs e)
        {
            if (ChangedMachineStatus != null)
            {
                ChangedMachineStatus(this, e);
            }
        }

        public ResponseConnectableDevice ConnectableDevice()
        {
            if (PhoneControl.Instance == null)
            {
                return new ResponseConnectableDevice { ErrorMessage = "PhoneService: Phone Instance not created", Successful = false };
            }
            return PhoneControl.Instance.ConnectableDevice();
        }

        public ResponseConnectableDevice Device()
        {
            if (PhoneControl.Instance == null)
            {
                return new ResponseConnectableDevice { ErrorMessage = "PhoneService: Phone Instance not created", Successful = false };
            }
            return PhoneControl.Instance.Device();
        }

        public ResponseConnectableDevice SelectConnectableDevice(string namedevice)
        {
            return PhoneControl.Instance.SelectConnectableDevice(namedevice);
        }

        public ResponseVoid Connect()
        {
            return PhoneControl.Instance.Connect();
        }

        public ResponseVoid CloseEmulator(string title)
        {
            return PhoneControl.Instance.CloseEmulator(title);
        }

        public ResponseVirtualMachines Machines(bool reload)
        {
            return PhoneControl.Instance.Machines(reload);
        }

        public ResponseVoid CleanUpMachines()
        {
            return PhoneControl.Instance.CleanUpMachines();
        }

        public ResponseVoid CloseMachine(string nameVm)
        {
            return PhoneControl.Instance.CloseMachine(nameVm);
        }

        public ResponseVoid CreateSnapshot(string vmName, string nameSnapshot)
        {
            return PhoneControl.Instance.CreateSnapshot(vmName, nameSnapshot);
        }

        public ResponseVoid DeleteSnapshot(string vmName, string nameSnapshot)
        {
            return PhoneControl.Instance.DeleteSnapshot(vmName, nameSnapshot);
        }

        public void CloseXdeVirtualMachines()
        {
            PhoneControl.Instance.CloseXdeVirtualMachines();
        }

        public VirtualMachine FindVirtualMachine(string vmName)
        {
            return PhoneControl.Instance.FindVirtualMachine(vmName);
        }

        public event EventHandler<ChangedMachineStatusEventArgs> ChangedMachineStatus;

        public ResponseVoid ConnectPhone(string guidDevice)
        {
            return PhoneControl.Instance.ConnectPhone(guidDevice);
        }

        public ResponseVoid IsConnected()
        {
            return PhoneControl.Instance.IsConnected();
        }

        public ResponseSystemInfo SystemInfo()
        {
            if (!IsConnected().Successful)
            {
                return new ResponseSystemInfo { InstructionSet = string.Empty, ProcessorArchitecture = String.Empty, Successful = false };
            }
            return PhoneControl.Instance.SystemInfo();
        }

        public ResponseVoid Disconnect()
        {
            if (IsConnected().Successful)
            {
                return PhoneControl.Instance.Disconnect();
            }
            return  new ResponseVoid{Successful = true};
        }

        public ResponseVoid Launch(string guidapp)
        {
            if (!IsConnected().Successful)
            {
                return new ResponseVoid { ErrorMessage = "Phone Not connected", Successful = false };
            }
            return PhoneControl.Instance.Launch(guidapp);
        }

        public ResponseVoid TerminateRunningInstances(string guidapp)
        {
            if (!IsConnected().Successful)
            {
                return new ResponseVoid { ErrorMessage = "Phone Not connected", Successful = false };
            }
            return PhoneControl.Instance.TerminateRunningInstances(guidapp);
        }

        public ResponseVoid Uninstall(string guidapp)
        {
            if (!IsConnected().Successful)
            {
                return new ResponseVoid { ErrorMessage = "Phone Not connected", Successful = false };
            }
            return PhoneControl.Instance.Uninstall(guidapp);
        }

        public ResponseVoid InstallApplication(Guid guid, Guid instance, string genre, string iconpath,
                                               string xapPackege)
        {
            if (!IsConnected().Successful)
            {
                return new ResponseVoid { ErrorMessage = "Phone Not connected", Successful = false };
            }
            return PhoneControl.Instance.InstallApplication(guid, instance, genre, iconpath, xapPackege);
        }

        public ResponseVoid IsApplicationInstalled(Guid guidapp)
        {
            if (!IsConnected().Successful)
            {
                return new ResponseVoid { ErrorMessage = "Phone Not connected", Successful = false };
            }
            return PhoneControl.Instance.IsApplicationInstalled(guidapp);
        }

        public ResponseVoid UpdateApplication(string guidapp, string genre, string iconfile, string filename)
        {
            if (!IsConnected().Successful)
            {
                return new ResponseVoid { ErrorMessage = "Phone Not connected", Successful = false };
            }
            return PhoneControl.Instance.UpdateApplication(guidapp, genre, iconfile, filename);
        }

        public ResponseArrayString ApplicationsInstalled()
        {
            if (!IsConnected().Successful)
            {
                return new ResponseArrayString { ErrorMessage = "Phone Not connected", Successful = false };
            }
            return PhoneControl.Instance.ApplicationsInstalled();
        }

        public ResponseRemoteFile GetIsoFiles(string guidapp, string pathRoot)
        {
            if (!IsConnected().Successful)
            {
                return new ResponseRemoteFile { ErrorMessage = "Phone Not connected", Successful = false };
            }
            return PhoneControl.Instance.GetIsoFiles(guidapp, pathRoot);
        }

        public ResponseVoid CopySendFile(string guidapp, RemoteFile isofileinfo, string newfile, bool overwrite)
        {
            if (!IsConnected().Successful)
            {
                return new ResponseVoid { ErrorMessage = "Phone Not connected", Successful = false };
            }
            if (!overwrite)
            {
                if (FileExists(guidapp, isofileinfo.FullName).Successful)
                {
                    return new ResponseVoid { ErrorMessage = "File already exists", Successful = false };
                }
            }
            return PhoneControl.Instance.CopySendFile(guidapp, isofileinfo, newfile, overwrite);
        }

        public ResponseVoid CopyReceiveFile(string guidapp, RemoteFile isofileinfo, string desktopTarget)
        {
            if (!IsConnected().Successful)
            {
                return new ResponseVoid { ErrorMessage = "Phone Not connected", Successful = false };
            }
            return PhoneControl.Instance.CopyReceiveFile(guidapp, isofileinfo, desktopTarget);
        }

        public ResponseVoid RenameFile(string guidapp, RemoteFile isofileinfo, string newfile)
        {
            if (!IsConnected().Successful)
            {
                return new ResponseVoid { ErrorMessage = "Phone Not connected", Successful = false };
            }
            return PhoneControl.Instance.CopyReceiveFile(guidapp, isofileinfo, newfile);
        }

        public ResponseVoid DeleteFile(string guidapp, RemoteFile isofileinfo)
        {
            if (!IsConnected().Successful)
            {
                return new ResponseVoid { ErrorMessage = "Phone Not connected", Successful = false };
            }
            return PhoneControl.Instance.DeleteFile(guidapp, isofileinfo);
        }

        public ResponseVoid DeleteDir(string guidapp, RemoteFile isofileinfo)
        {
            if (!IsConnected().Successful)
            {
                return new ResponseVoid { ErrorMessage = "Phone Not connected", Successful = false };
            }
            return PhoneControl.Instance.DeleteDir(guidapp, isofileinfo);
        }

        public ResponseVoid DirectoryExists(string guidapp, string folder)
        {
            if (!IsConnected().Successful)
            {
                return new ResponseVoid { ErrorMessage = "Phone Not connected", Successful = false };
            }
            return PhoneControl.Instance.DirectoryExists(guidapp, folder);
        }

        public ResponseVoid FileExists(string guidapp, string file)
        {
            if (!IsConnected().Successful)
            {
                return new ResponseVoid { ErrorMessage = "Phone Not connected", Successful = false };
            }
            return PhoneControl.Instance.FileExists(guidapp, file);
        }

        public ResponseVoid CreateDir(string guidapp, RemoteFile isofileinfo, string newfolder)
        {
            if (!IsConnected().Successful)
            {
                return new ResponseVoid { ErrorMessage = "Phone Not connected", Successful = false };
            }
            return PhoneControl.Instance.CreateDir(guidapp, isofileinfo, newfolder);
        }

        public override void InitService()
        {
            PhoneControl.Instance.InitService();
            _critialError = PhoneControl.Instance.CriticalError;
            if (_critialError == null)
            {
                base.InitService();
            }
        }

        public override void Start()
        {
            if (_critialError != null)
            {
                return;
            }
            PhoneControl.Instance.Start();
            _critialError = PhoneControl.Instance.CriticalError;
            if (_critialError != null)
            {
                return;
            }
            base.Start();
        }

        public override void Stop()
        {
            PhoneControl.Instance.Stop();
            base.Stop();
        }

        public override bool IsRunning()
        {
            var ok = base.IsRunning();
            if (ok)
            {
                ok = PhoneControl.Instance.IsRunning();
            }
            return ok;
        }
    }
}